package basic

import (
	"bytes"
	"fmt"
	"github.com/disintegration/imaging"
	"github.com/gin-gonic/gin"
	ffmpeg "github.com/u2takey/ffmpeg-go"
	"log"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"project/controller"
	"project/mySql"
	"strings"
	"time"
)

/**
 * @File : publish.go
 * @Description : 发布视频，个人主页的视频列表
 * @Author : 王帅、吴概
 * @Date : 2023/2/12
 */

// VideoListResponse 视频列表的返回
type VideoListResponse struct {
	controller.Response
	VideoList []controller.Video `json:"video_list"`
}

var r *gin.Engine

func PubR(r1 *gin.Engine) {
	r = r1
}

// 生成个人主页视频的封面图
func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string) {
	buf := bytes.NewBuffer(nil)
	err := ffmpeg.Input(videoPath).
		Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}).
		Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}).
		WithOutput(buf, os.Stdout).
		Run()
	if err != nil {
		log.Fatal("生成缩略图失败：", err)
	}

	img, err := imaging.Decode(buf)
	if err != nil {
		log.Fatal("生成缩略图失败：", err)
	}

	err = imaging.Save(img, snapshotPath+".jpeg")
	if err != nil {
		log.Fatal("生成缩略图失败：", err)
	}

	// 成功则返回生成的缩略图名
	names := strings.Split(snapshotPath, "\\")
	snapshotName = names[len(names)-1] + ".jpeg"
	return
}

// Publish 在本机关闭服务器的情况下，已投稿的视频会无法播放，
// check token then save upload file to public directory
// 连接接口以及从本地视频文件中选择投稿
func Publish(c *gin.Context) {
	token := c.PostForm("token")
	user := mySql.GetUserByToken(token)
	data, err := c.FormFile("data")
	if err != nil {
		c.JSON(http.StatusOK, controller.Response{
			StatusCode: 1,
			StatusMsg:  err.Error(),
		})
		return
	}

	filename := filepath.Base(data.Filename)
	finalName := fmt.Sprintf("%d_%s", user.Id, filename)
	saveFile := filepath.Join("./public/", finalName)
	fmt.Println("aa=" + saveFile)
	if err := c.SaveUploadedFile(data, saveFile); err != nil {
		c.JSON(http.StatusOK, controller.Response{
			StatusCode: 1,
			StatusMsg:  err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, controller.Response{
		StatusCode: 0,
		StatusMsg:  finalName + " uploaded successfully",
	}) //视频上传成功
	rand.Seed(time.Now().Unix())
	//var id1 = rand.Int() //生成随机视频id
	title := c.PostForm("title")
	user.WorkCount = user.WorkCount + 1
	fmt.Println("wss=" + title)
	GetSnapshot(saveFile, "./public/"+finalName, 1)
	r.GET("/"+finalName, func(c *gin.Context) {
		c.File("./public/" + finalName)

	}) //将已投稿的文件从目录转为可以访问的url 如http://198.162.18.6:8080/finalName
	filename1 := finalName + ".jpeg"
	r.GET("/"+filename1, func(c *gin.Context) {
		c.File("./public/" + filename1)
	})
	var video = controller.Video{
		Author:        user,
		PlayUrl:       controller.GetCompleteIpv4Address() + finalName,
		CoverUrl:      controller.GetCompleteIpv4Address() + filename1,
		FavoriteCount: 0,
		CommentCount:  0,
		Title:         title,
		AuthorId:      user.Id,
		IsFavorite:    false,
	}
	//将创建好的video加入DemoVideos
	mySql.SaveUser(user)
	mySql.NewVideosData(video)

	//保存publish
	publish := mySql.GetPublish(user.Id)
	publish.PublishList = controller.AddId(publish.PublishList, mySql.GetLastVideoId())
	mySql.SavePublish(publish)
}

// PublishList 作品列表
func PublishList(c *gin.Context) {
	id := controller.ParseInt(c.Query("user_id"))            //获取id
	publish := mySql.GetPublish(id)                          //获取publish类
	publishList := controller.GetIdList(publish.PublishList) //根据publish类里的字符串形式PublishList获取int数组形式的publishList
	c.JSON(http.StatusOK, VideoListResponse{
		Response:  controller.Response{StatusCode: 0},
		VideoList: mySql.GetVideoListByIdList(publishList), //根据int数组形式的publishList（视频id列表）获取视频列表
	})
}
